//
//  NetWorkTools.m
//  singleTarget
//
//  Created by   李小云 on 17/9/20.
//  Copyright © 2017年   李小云. All rights reserved.
//

#import "NetWorkTools.h"
#import "NetWorkRequestModel.h"
#import "AFNetworking.h"
#import "YYCacheManger.h"

@interface NetWorkTools  ()

@property(nonatomic, strong)YYCacheManger *cacheManger;

@end

@implementation NetWorkTools

#pragma mark -单粒
+(instancetype)shareNetWorkTools
{
    static NetWorkTools *tools = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        tools = [[NetWorkTools alloc]init];
        
    });
    return tools;
}

#pragma mark -init
-(instancetype)init
{
    if (self = [super init]) {
        _manger = [AFHTTPSessionManager manager];
        _cacheManger = [YYCacheManger manger];
    }
    
    return self;
}


#pragma mark - public
-(NSURLSessionTask *)requestWithModel:(NetWorkRequestModel *)model
{
    NSURLSessionTask *task = nil;
    NSURL *RequestUrl = [NSURL URLWithString:model.url];
    
    if (!RequestUrl) {
        //url编码问题
        NSString *realStr = [model.url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        
        RequestUrl = [NSURL URLWithString:realStr];
        if (!RequestUrl) {
            NSLog(@"request url error %@",model.url);
            
            model.FailRequestBlock(nil, [NSError errorWithDomain:model.url code:3841 userInfo:@{@"error":@"url error"}]);
            return task;
        }
        model.url =  realStr;
    }
    
    //afn 序列化设置
    if (model.isJsonRequetFormat) {
        _manger.requestSerializer = [AFJSONRequestSerializer serializer];
    }else{
        _manger.requestSerializer = [AFHTTPRequestSerializer serializer];
    }
    
    if (model.isNSDataReponseFormat) {
        _manger.responseSerializer = [AFHTTPResponseSerializer serializer];
    }else{
        _manger.responseSerializer = [AFJSONResponseSerializer serializer];
    }
    
    _manger.requestSerializer.timeoutInterval = 15.0f;
 
    model.headParms = @{@"version":@"1.0"};
    [self setUpHeadParms:model.headParms];
    
    switch (model.requestType) {
        case NetWorkRequestGet:{
          
            task = [self requestWithGetModel:model];
            
        }
            break;
        case NetWorkRequestPost:{
            
            task = [self requestWithPostModel:model];
        }
            break;
        case NetWorkRequestUpLoad:{
            
            task = [self requestWithUpLoadModel:model];
        }
            break;
        case NetWorkRequestDownLoad:{
            
            task = [self requestWithDownLoadModel:model];
        }
            break;
        default:
            break;
    }
    
    return task;
    
}

#pragma mark -header
- (void)setUpHeadParms:(NSDictionary *)headParms
{
    if (headParms && [headParms isKindOfClass:[NSDictionary class]]) {
        for (NSString *key in headParms.allKeys) {
            if ([key isKindOfClass:[NSString class]] && ![key isEqualToString:@""] && headParms[key]) {
                [_manger.requestSerializer setValue:headParms[key] forHTTPHeaderField:key];
            }
        }
    }
    
}

#pragma mark -get
-(NSURLSessionDataTask *)requestWithGetModel:(NetWorkRequestModel *)requestModel
{
    
    NSURLSessionDataTask *dataTask = nil;
    
    NSMutableURLRequest *request = [_manger.requestSerializer requestWithMethod:@"GET" URLString:requestModel.url parameters:requestModel.parms error:nil];
    
    switch (requestModel.CachesType) {
        case CachesNone: //无需缓存
        {
            dataTask = [self requestWithGetCachesModel:requestModel needCaches:NO];
        }
            break;
        case CachesOnlyLocal: //只取缓存
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                id cacheObject = nil;
                NSString *key = request.URL.absoluteString;
                if ([_cacheManger containsObjectForKey:key]) {
                    cacheObject = [_cacheManger objectForKey:key];
                }
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    if (requestModel.cachesBlock) {
                        requestModel.cachesBlock(cacheObject);
                    }
                    
                });
                
            });
        }
            break;
        case CachesOnlyRemoteButCaches: //取网络数据并缓存
        {
            dataTask = [self requestWithGetCachesModel:requestModel needCaches:YES];
        }
            break;
        case CachesFirstLocalAndRemote: //先本地在缓存 响应两次
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                id cacheObject = nil;
                NSString *key = request.URL.absoluteString;
                if ([_cacheManger containsObjectForKey:key]) {
                    cacheObject = [_cacheManger objectForKey:key];
                }
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    if (requestModel.cachesBlock) {
                        requestModel.cachesBlock(cacheObject);
                    }
                    
                });
                
            });
            dataTask = [self requestWithGetCachesModel:requestModel needCaches:YES];
        }
            break;
         case CachesFirstLocalOrRemote: //有本地先取本地 没有在取网络数据
        {
            NSString *key = request.URL.absoluteString;
            if ([_cacheManger containsObjectForKey:key]) {
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    [_cacheManger objectForKey:key withBlock:^(NSString *key, id<NSCoding> object) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            if (requestModel.cachesBlock) {
                                requestModel.cachesBlock(object);
                            }
                        });
                    }];
                });
                
            }else{
                
                 dataTask = [self requestWithGetCachesModel:requestModel needCaches:YES];
            }
            
        }
        default:
            break;
    }
    
    
    return dataTask;
    
    
}

- (NSURLSessionDataTask *)requestWithGetCachesModel:(NetWorkRequestModel *)requestModel needCaches:(BOOL)needCaches
{
    NSURLSessionDataTask *dataTask = [_manger GET:requestModel.url parameters:requestModel.parms progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        if (needCaches) {
            if (responseObject && ![responseObject isKindOfClass:[NSNull class]]) {

                NSString *key = task.currentRequest.URL.absoluteString;
               [_cacheManger setObject:responseObject forKey:key withBlock:^{
                    dispatch_async(dispatch_get_main_queue(), ^{
                        
                    });
               }];
            }
            
        }
        
        if (requestModel.successRequestBlock) {
            requestModel.successRequestBlock (task,responseObject);
        }
        
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (requestModel.FailRequestBlock) {
            requestModel.FailRequestBlock(task,error);
        }
        
    }];
    
    return dataTask;
    
}

#pragma mark -post
-(NSURLSessionDataTask *)requestWithPostModel:(NetWorkRequestModel *)requestModel
{
    NSURLSessionDataTask *postTalk = [self.manger POST:requestModel.url parameters:requestModel.parms progress:nil success:requestModel.successRequestBlock failure:requestModel.FailRequestBlock];
   
    return postTalk;
}

#pragma mark -upload
-(NSURLSessionDataTask *)requestWithUpLoadModel:(NetWorkRequestModel *)requestModel
{
    NSURLSessionDataTask *postTalk = [self.manger POST:requestModel.url parameters:requestModel.parms constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        [formData appendPartWithFileData:requestModel.fileData name:requestModel.dataName fileName:requestModel.fileName mimeType:requestModel.mimeType];
       
        
    } progress:nil success:requestModel.successRequestBlock failure:requestModel.FailRequestBlock];
    
    return postTalk;
}
#pragma mark -Download
-(NSURLSessionDataTask *)requestWithDownLoadModel:(NetWorkRequestModel *)requestModel
{
    NSURL *url = [NSURL URLWithString:requestModel.url];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    NSURLSessionDataTask *Download = [_manger downloadTaskWithRequest:request progress:nil destination:nil completionHandler:nil];

    return Download;
}

@end
